package com.ala4.oxcafe.service.impl;

import com.ala4.oxcafe.boot.aop.VisitCounterService;
import com.ala4.oxcafe.common.utils.collection.CollUtil;
import com.ala4.oxcafe.common.utils.date.DateUtil;
import com.ala4.oxcafe.dto.BackendHomeDTO;
import com.ala4.oxcafe.entity.ServiceOrder;
import com.ala4.oxcafe.entity.ServiceOrderDetail;
import com.ala4.oxcafe.entity.StoreInfo;
import com.ala4.oxcafe.repository.ServiceOrderDetailRepository;
import com.ala4.oxcafe.repository.ServiceOrderRepository;
import com.ala4.oxcafe.repository.StoreInfoRepository;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 后台首页数据统计
 *
 * @author PING
 * @version 1.0.0
 * @date 2025/8/18 11:39
 */
@Service
@AllArgsConstructor
public class BackendHomeService {

    private final VisitCounterService visitCounterService;

    private final StoreInfoRepository storeInfoRepository;

    private final ServiceOrderRepository serviceOrderRepository;

    private final ServiceOrderDetailRepository serviceOrderDetailRepository;

    public BackendHomeDTO backendHomeInfo() {
        BackendHomeDTO backendHomeDTO = new BackendHomeDTO();

        // 今日访问数量
        backendHomeDTO.setVisitorCount(visitCounterService.getDailyVisitCount(VisitCounterService.BIZ_TYPE_VISITOR_COUNT));
        // 门店数量
        backendHomeDTO.setStoreCount(storeInfoRepository.count(Wrappers.<StoreInfo>lambdaQuery()));

        // 今天
        LocalDate now = LocalDate.now();
        // 明天
        LocalDate nextNow = now.plusDays(1);
        // 服务单数量
        backendHomeDTO.setServiceOrderCount(serviceOrderRepository.count(Wrappers.<ServiceOrder>lambdaQuery().ge(ServiceOrder::getServiceDate, now).lt(ServiceOrder::getServiceDate, nextNow)));
        // 施工车衣数量
        backendHomeDTO.setProductOrderCount(serviceOrderDetailRepository.count(Wrappers.<ServiceOrderDetail>lambdaQuery().ge(ServiceOrderDetail::getCreateTime, now).lt(ServiceOrderDetail::getCreateTime, nextNow)));

        // 本月系列施工数量
        List<BackendHomeDTO.MonthProductDTO> moomProductList = serviceOrderDetailRepository.monthProductCount();
        this.calculateRatio(moomProductList);
        backendHomeDTO.setMoomProductList(moomProductList);

        // 最近六个月车衣施工数量
        List<BackendHomeDTO.SixMonthProduct> sixMonthProductList = serviceOrderDetailRepository.lastSixMonthProductCount();
        backendHomeDTO.setSixMonthProductCount(this.completeLastSixMonths(sixMonthProductList));

        return backendHomeDTO;
    }

    /**
     * 计算占比
     *
     * @param list
     */
    public void calculateRatio(List<BackendHomeDTO.MonthProductDTO> list) {
        // 1. 计算总施工数量
        int totalCount = list.stream()
                .mapToInt(BackendHomeDTO.MonthProductDTO::getSeriesCount)
                .sum();

        // 如果总数为0，则占比无法计算（避免除零异常）
        if (totalCount == 0) {
            list.forEach(dto -> dto.setRatio(BigDecimal.ZERO));
            return;
        }

        // 2. 遍历计算每个DTO的占比
        for (BackendHomeDTO.MonthProductDTO dto : list) {
            BigDecimal ratio = BigDecimal.valueOf(dto.getSeriesCount())
                    .multiply(BigDecimal.valueOf(100))  // 转换为百分比
                    .divide(BigDecimal.valueOf(totalCount), 4, RoundingMode.HALF_UP); // 保留4位小数

            dto.setRatio(ratio);
        }
    }

    /**
     * 补全最近6个月数据，缺失月份数量设为0
     *
     * @param originalList 原始数据列表
     * @return 包含最近6个月数据的完整列表
     */
    public List<BackendHomeDTO.SixMonthProduct> completeLastSixMonths(List<BackendHomeDTO.SixMonthProduct> originalList) {

        // 2. 将原始列表转换为Map便于快速查找（月份字符串 -> 数据对象）
        Map<String, BackendHomeDTO.SixMonthProduct> monthDataMap = originalList.stream()
                .collect(Collectors.toMap(BackendHomeDTO.SixMonthProduct::getMonthStr, data -> data));

        // 3. 获取当前日期（今天是2025-08-18）
        LocalDate currentDate = LocalDate.now();

        // 4. 创建结果列表
        List<BackendHomeDTO.SixMonthProduct> result = CollUtil.newArrayList();

        // 5. 生成最近6个月（从当前月往前推5个月）
        for (int i = 5; i >= 0; i--) {

            String monthStr = DateUtil.dateToString(currentDate.plusMonths(-i), "yyyy-MM");

            // 如果存在该月数据则使用，否则创建新对象（数量为0）
            BackendHomeDTO.SixMonthProduct data = monthDataMap.getOrDefault(monthStr,
                    new BackendHomeDTO.SixMonthProduct(monthStr, BigDecimal.ZERO));

            result.add(data);
        }

        return result;
    }
}
